<template>
  <div class="performance-chart">
    <div class="chart-header">
      <div class="chart-title-section">
        <h3>{{ title }}</h3>
        <div class="metric-description" v-if="getCurrentMetric().description">
          {{ getCurrentMetric().description }}
        </div>
      </div>
      <div class="chart-controls">
        <select v-model="selectedMetric" @change="updateChart">
          <option value="responseTime">响应时间</option>
          <option value="size">资源大小</option>
          <option value="requests">请求数量</option>
          <option value="dnsTime">DNS解析时间</option>
          <option value="connectTime">连接建立时间</option>
          <option value="sslTime">SSL握手时间</option>
          <option value="ttfb">首字节时间</option>
          <option value="cacheHitRate">缓存命中率</option>
          <option value="redirectTime">重定向时间</option>
          <option value="downloadTime">下载时间</option>
        </select>
      </div>
    </div>
    <div class="chart-container">
      <canvas ref="chartCanvas"></canvas>
    </div>
    <div class="chart-legend">
      <div class="legend-item">
        <div class="legend-color baseline"></div>
        <span>基准文件</span>
      </div>
      <div class="legend-item">
        <div class="legend-color target"></div>
        <span>对比文件</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
import type { PerformanceMetrics } from '../../types/har';

// Props
interface Props {
  baselineMetrics: PerformanceMetrics;
  targetMetrics: PerformanceMetrics;
  title?: string;
}

const props = withDefaults(defineProps<Props>(), {
  title: '性能对比图表'
});

// Reactive data
const chartCanvas = ref<HTMLCanvasElement>();
const selectedMetric = ref<string>('responseTime');
let chart: any = null;

// Chart data mapping
const metricMapping = {
  responseTime: {
    baseline: 'averageResponseTime',
    target: 'averageResponseTime',
    label: '平均响应时间 (ms)',
    description: '所有请求的平均响应时间',
    unit: 'ms'
  },
  size: {
    baseline: 'totalSize',
    target: 'totalSize',
    label: '总资源大小 (bytes)',
    description: '所有资源的总大小',
    unit: 'bytes'
  },
  requests: {
    baseline: 'totalRequests',
    target: 'totalRequests',
    label: '总请求数量',
    description: 'HTTP请求的总数量',
    unit: '个'
  },
  dnsTime: {
    baseline: 'averageDnsTime',
    target: 'averageDnsTime',
    label: 'DNS解析时间 (ms)',
    description: '平均DNS解析时间',
    unit: 'ms'
  },
  connectTime: {
    baseline: 'averageConnectTime',
    target: 'averageConnectTime',
    label: '连接建立时间 (ms)',
    description: '平均TCP连接建立时间',
    unit: 'ms'
  },
  sslTime: {
    baseline: 'averageSslTime',
    target: 'averageSslTime',
    label: 'SSL握手时间 (ms)',
    description: '平均SSL/TLS握手时间',
    unit: 'ms'
  },
  ttfb: {
    baseline: 'averageTtfb',
    target: 'averageTtfb',
    label: '首字节时间 (ms)',
    description: '平均Time to First Byte',
    unit: 'ms'
  },
  cacheHitRate: {
    baseline: 'cacheHitRate',
    target: 'cacheHitRate',
    label: '缓存命中率 (%)',
    description: '缓存命中的请求比例',
    unit: '%'
  },
  redirectTime: {
    baseline: 'averageRedirectTime',
    target: 'averageRedirectTime',
    label: '重定向时间 (ms)',
    description: '平均重定向处理时间',
    unit: 'ms'
  },
  downloadTime: {
    baseline: 'averageDownloadTime',
    target: 'averageDownloadTime',
    label: '下载时间 (ms)',
    description: '平均内容下载时间',
    unit: 'ms'
  }
};

// Methods
function createChart() {
  if (!chartCanvas.value) return;
  
  const ctx = chartCanvas.value.getContext('2d');
  if (!ctx) return;
  
  const metric = metricMapping[selectedMetric.value as keyof typeof metricMapping];
  const baselineValue = props.baselineMetrics[metric.baseline as keyof PerformanceMetrics] as number;
  const targetValue = props.targetMetrics[metric.target as keyof PerformanceMetrics] as number;
  
  // 简单的条形图实现
  const canvas = chartCanvas.value;
  const width = canvas.width;
  const height = canvas.height;
  
  // 清除画布
  ctx.clearRect(0, 0, width, height);
  
  // 设置样式
  ctx.font = '14px Arial';
  ctx.textAlign = 'center';
  
  // 计算条形图参数
  const barWidth = width * 0.3;
  const barSpacing = width * 0.1;
  const maxValue = Math.max(baselineValue, targetValue);
  const scale = (height - 60) / maxValue;
  
  // 绘制基准文件条形
  const baselineX = width * 0.2;
  const baselineHeight = baselineValue * scale;
  const baselineY = height - 40 - baselineHeight;
  
  // 绘制基准文件条形（带渐变）
  const baselineGradient = ctx.createLinearGradient(0, baselineY, 0, baselineY + baselineHeight);
  baselineGradient.addColorStop(0, '#3b82f6');
  baselineGradient.addColorStop(1, '#1d4ed8');
  ctx.fillStyle = baselineGradient;
  ctx.fillRect(baselineX, baselineY, barWidth, baselineHeight);
  
  // 添加基准文件条形阴影
  ctx.shadowColor = 'rgba(59, 130, 246, 0.3)';
  ctx.shadowBlur = 10;
  ctx.shadowOffsetY = 4;
  ctx.fillRect(baselineX, baselineY, barWidth, baselineHeight);
  ctx.shadowColor = 'transparent';
  ctx.shadowBlur = 0;
  ctx.shadowOffsetY = 0;
  
  // 绘制对比文件条形
  const targetX = width * 0.6;
  const targetHeight = targetValue * scale;
  const targetY = height - 40 - targetHeight;
  
  // 绘制对比文件条形（带渐变）
  const targetGradient = ctx.createLinearGradient(0, targetY, 0, targetY + targetHeight);
  targetGradient.addColorStop(0, '#10b981');
  targetGradient.addColorStop(1, '#059669');
  ctx.fillStyle = targetGradient;
  ctx.fillRect(targetX, targetY, barWidth, targetHeight);
  
  // 添加对比文件条形阴影
  ctx.shadowColor = 'rgba(16, 185, 129, 0.3)';
  ctx.shadowBlur = 10;
  ctx.shadowOffsetY = 4;
  ctx.fillRect(targetX, targetY, barWidth, targetHeight);
  ctx.shadowColor = 'transparent';
  ctx.shadowBlur = 0;
  ctx.shadowOffsetY = 0;
  
  // 绘制标签
  ctx.font = 'bold 14px Arial';
  ctx.fillStyle = '#1e293b';
  ctx.textAlign = 'center';
  ctx.fillText('基准文件', baselineX + barWidth / 2, height - 20);
  ctx.fillText('对比文件', targetX + barWidth / 2, height - 20);
  
  // 绘制数值背景
  const valuePadding = 8;
  const valueHeight = 24;
  
  // 基准文件数值背景
  const baselineValueWidth = ctx.measureText(formatValue(baselineValue)).width + valuePadding * 2;
  const baselineValueX = baselineX + barWidth / 2 - baselineValueWidth / 2;
  const baselineValueY = baselineY - 10 - valueHeight / 2;
  
  ctx.fillStyle = 'rgba(59, 130, 246, 0.1)';
  ctx.fillRect(baselineValueX, baselineValueY, baselineValueWidth, valueHeight);
  ctx.strokeStyle = '#3b82f6';
  ctx.lineWidth = 1;
  ctx.strokeRect(baselineValueX, baselineValueY, baselineValueWidth, valueHeight);
  
  // 对比文件数值背景
  const targetValueWidth = ctx.measureText(formatValue(targetValue)).width + valuePadding * 2;
  const targetValueX = targetX + barWidth / 2 - targetValueWidth / 2;
  const targetValueY = targetY - 10 - valueHeight / 2;
  
  ctx.fillStyle = 'rgba(16, 185, 129, 0.1)';
  ctx.fillRect(targetValueX, targetValueY, targetValueWidth, valueHeight);
  ctx.strokeStyle = '#10b981';
  ctx.lineWidth = 1;
  ctx.strokeRect(targetValueX, targetValueY, targetValueWidth, valueHeight);
  
  // 绘制数值
  ctx.font = 'bold 12px Arial';
  ctx.fillStyle = '#1e293b';
  ctx.fillText(formatValue(baselineValue), baselineX + barWidth / 2, baselineY - 10);
  ctx.fillText(formatValue(targetValue), targetX + barWidth / 2, targetY - 10);
  
  // 绘制标题
  ctx.font = 'bold 18px Arial';
  ctx.fillStyle = '#1e293b';
  ctx.textAlign = 'center';
  ctx.fillText(metric.label, width / 2, 30);
}

function formatValue(value: number): string {
  const metric = getCurrentMetric();
  
  if (selectedMetric.value === 'size') {
    return formatFileSize(value);
  } else if (selectedMetric.value === 'cacheHitRate') {
    return `${value.toFixed(1)}%`;
  } else if (selectedMetric.value === 'requests') {
    return value.toFixed(0);
  } else if (['responseTime', 'dnsTime', 'connectTime', 'sslTime', 'ttfb', 'redirectTime', 'downloadTime'].includes(selectedMetric.value)) {
    return `${value.toFixed(0)}ms`;
  } else {
    return value.toFixed(2);
  }
}

function formatFileSize(bytes: number): string {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

function getCurrentMetric() {
  return metricMapping[selectedMetric.value as keyof typeof metricMapping] || metricMapping.responseTime;
}

function updateChart() {
  nextTick(() => {
    createChart();
  });
}

function resizeChart() {
  if (!chartCanvas.value) return;
  
  const container = chartCanvas.value.parentElement;
  if (!container) return;
  
  const rect = container.getBoundingClientRect();
  chartCanvas.value.width = rect.width;
  chartCanvas.value.height = 300;
  
  updateChart();
}

// Lifecycle
onMounted(() => {
  resizeChart();
  window.addEventListener('resize', resizeChart);
});

onUnmounted(() => {
  window.removeEventListener('resize', resizeChart);
});

// Watchers
watch(() => props.baselineMetrics, updateChart, { deep: true });
watch(() => props.targetMetrics, updateChart, { deep: true });
</script>

<style scoped>
.performance-chart {
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
  border-radius: 20px;
  padding: 32px;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.2);
  position: relative;
  overflow: hidden;
}

.performance-chart::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 50%, #06b6d4 100%);
  box-shadow: 0 0 20px rgba(59, 130, 246, 0.3);
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 24px;
  position: relative;
  z-index: 1;
  gap: 24px;
}

.chart-title-section {
  flex: 1;
  min-width: 0;
}

.chart-title-section h3 {
  margin: 0 0 8px 0;
  color: var(--text-primary);
  font-size: 22px;
  font-weight: 700;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  background: linear-gradient(135deg, #1e293b, #475569);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.metric-description {
  font-size: 14px;
  color: var(--text-secondary);
  font-weight: 500;
  line-height: 1.4;
  background: var(--primary-50);
  padding: 8px 12px;
  border-radius: var(--radius-md);
  border-left: 3px solid var(--primary-500);
}

.chart-controls select {
  padding: 12px 20px;
  border: 2px solid #e2e8f0;
  border-radius: 12px;
  font-size: 15px;
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
  color: var(--text-primary);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  font-weight: 600;
  min-width: 140px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  position: relative;
  overflow: hidden;
}

.chart-controls select::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.05) 0%, rgba(139, 92, 246, 0.05) 100%);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.chart-controls select:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1);
  transform: translateY(-2px);
}

.chart-controls select:hover {
  border-color: #3b82f6;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.chart-container {
  position: relative;
  width: 100%;
  height: 320px;
  margin-bottom: 20px;
  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
  border-radius: 16px;
  padding: 20px;
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.06);
}

.chart-container canvas {
  width: 100%;
  height: 100%;
  border: 1px solid rgba(226, 232, 240, 0.5);
  border-radius: 12px;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.chart-legend {
  display: flex;
  justify-content: center;
  gap: 32px;
  margin-top: 16px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 20px;
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
  border-radius: 12px;
  border: 1px solid rgba(226, 232, 240, 0.5);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  font-weight: 600;
  color: var(--text-primary);
}

.legend-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.legend-color {
  width: 20px;
  height: 20px;
  border-radius: 6px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  position: relative;
  overflow: hidden;
}

.legend-color::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.1));
  border-radius: 6px;
}

.legend-color.baseline {
  background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
}

.legend-color.target {
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
}
</style>
